package cn.yunyichina.provider.base.service.impl;

import cn.yunyichina.provider.base.dao.MedicalCardDao;
import cn.yunyichina.provider.base.dao.PersonalUserDao;
import cn.yunyichina.provider.base.dao.PersonalUserFamilyDao;
import cn.yunyichina.provider.base.entity.MedicalCard;
import cn.yunyichina.provider.base.entity.PersonalUserFamily;
import cn.yunyichina.provider.base.utils.IdCardUtils;
import cn.yunyichina.provider.base.vo.*;
import cn.yunyichina.provider.framework.annotation.validate.ValidateException;
import cn.yunyichina.provider.framework.annotation.validate.Validator;
import cn.yunyichina.provider.framework.common.PKGenerator;
import cn.yunyichina.provider.framework.dubbo.service.BaseService;
import cn.yunyichina.provider.framework.dubbo.service.HisifaceService;
import cn.yunyichina.provider.framework.exception.CallException;
import cn.yunyichina.provider.iface.entity.PersonalUser;
import cn.yunyichina.provider.iface.entity.base.Org;
import cn.yunyichina.provider.iface.entity.base.Rule;
import cn.yunyichina.provider.iface.entity.common.ResCommon;
import cn.yunyichina.provider.iface.entity.common.Response;
import cn.yunyichina.provider.iface.entity.common.ResponseObject;
import cn.yunyichina.provider.iface.entity.hisiface.base.CreateCardVo;
import cn.yunyichina.provider.iface.entity.hisiface.base.CreateCardVoResponse;
import cn.yunyichina.provider.iface.entity.hisiface.base.PatientVo;
import cn.yunyichina.provider.iface.entity.hisiface.base.PatientVoResponse;
import cn.yunyichina.utils.commons.DateUtils;
import cn.yunyichina.utils.commons.IDUtils;
import cn.yunyichina.utils.convert.JsonUtils;
import cn.yunyichina.utils.log.Log;
import cn.yunyichina.utils.log.constant.LogScene;
import cn.yunyichina.utils.security.MD5Util;
import com.alibaba.dubbo.common.utils.CollectionUtils;
import com.alibaba.dubbo.common.utils.StringUtils;
import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import javax.annotation.Resource;
import java.text.DateFormat;
import java.text.SimpleDateFormat;
import java.util.*;

/**
 * Created by 15-AK on 2017/8/15.
 */
@Service
public class PersonalServiceImpl {
    private static final Logger logger = LoggerFactory.getLogger(PersonalServiceImpl.class);
    private static final String HIS_NO_PATIENT = "提示：在医院查询不到该卡号，请检查后重新输入";
    private static final String HIS_MESSAGE_NOT_MATCH = "提示：填写的信息与医院登记的信息不一致，请检查后重新填写";
    private static final String HIS_CREATE_CARD_ERROR = "提示：建档失败请稍候重试";
    private static final String BIND_CARD_ERROR = "提示：绑卡失败，保存信息错误，请稍候重试";
    public static DateFormat YYYYMMDD = new SimpleDateFormat("yyyy-MM-dd");
    public static DateFormat YYYYMMDD8 = new SimpleDateFormat("yyyyMMdd");
    @Autowired
    private MedicalCardDao medicalCardDao;
    @Autowired
    private PersonalUserFamilyDao personalUserFamilyDao;
    @Autowired
    private PersonalUserDao personalUserDao;
    @Resource
    private OrgServiceImpl orgServiceImpl;

    /**
     * 删除就诊人
     *
     * @param strData
     * @return
     */
    public ResponseObject deletePersonalFamily(String strData) {
        ResponseObject responseObject = new ResponseObject();
        try {
            logger.info("移除就诊人入参strData={}", strData);
            JSONObject jsonObject = JSONObject.parseObject(strData);
            String id = jsonObject.getString("family_id");
            if (StringUtils.isBlank(id)) {
                responseObject.setResultCodeAndMessage("1001", "family_id 不能为空");
                return responseObject;
            }
            PersonalUserFamily personalUserFamily = new PersonalUserFamily();
            personalUserFamily.setId(id);
            personalUserFamily.setEnableFlag(new Short("0"));
            personalUserFamilyDao.update(personalUserFamily);


            medicalCardDao.deleteMedicalCardByFamilyId(id);
            responseObject.setResultCodeAndMessage("0", "移除就诊人成功");
            logger.info("移除就诊人成功");
        } catch (Exception e) {
            logger.error("移除就诊人异常 errMsg ={}", e.getMessage());
            responseObject.setResultCodeAndMessage("-1", "移除就诊人异常");
        }
        return responseObject;
    }

    /**
     * 查询就诊人列表(enable_flag =1 为启用的)
     *
     * @param strData
     * @return
     */
    public ResponseObject listPersonalFamily(String strData) {
        ResponseObject responseObject = new ResponseObject();
        try {

            logger.info("查询就诊人入参strData={}", strData);
            JSONObject jsonObject = JSONObject.parseObject(strData);
            String openId = jsonObject.getString("open_id");
            if (StringUtils.isBlank(openId)) {
                responseObject.setResultCodeAndMessage("1001", "open_id不能为空");
                return responseObject;
            }
            long beginTime_1 = System.currentTimeMillis();
            PersonalUser personalUser = personalUserDao.selectPersonalUserByOpenId(openId);
            long endTime_1 = System.currentTimeMillis();

            if (personalUser == null) {
                logger.info("通过openId ={} 换取userId 失败", openId);
                responseObject.setResultCodeAndMessage("1001", "通过openId 换取userId 失败");
                return responseObject;
            }
            long beginTime_2 = System.currentTimeMillis();
            List<PersonalUserFamily> personalUserFamililes = personalUserFamilyDao.selectFamilyByUserId(personalUser.getId());
            long endTime_2 = System.currentTimeMillis();

            List<PersonalUserFamilyResponseVo> familyResponseVoList = null;
            if (CollectionUtils.isNotEmpty(personalUserFamililes)) {
                familyResponseVoList = new ArrayList<>();
                for (PersonalUserFamily personalUserFamily : personalUserFamililes) {
                    familyResponseVoList.add(buildPersonalUserFamilyResponseVo(personalUserFamily));
                }
            }
            StringBuilder sb = new StringBuilder("selectPersonalUserByOpenId:");
            sb.append(endTime_1 - beginTime_1).append(";selectFamilyByUserId:").append(endTime_2 - beginTime_2);
            responseObject.setResultCodeAndMessage("0", "成功");
            responseObject.setResultObject(familyResponseVoList);
            responseObject.setTime(sb.toString());
            logger.info("查询就诊人成功 result ={}", new Object[]{JsonUtils.toJsonString(responseObject)});
        } catch (Exception e) {
            logger.error("查询就诊人异常 errMsg ={}", e.getMessage());
            responseObject.setResultCodeAndMessage("-1", "查询就诊人异常");
        }
        return responseObject;
    }

    private PersonalUserFamilyResponseVo buildPersonalUserFamilyResponseVo(PersonalUserFamily personalUserFamily) {
        PersonalUserFamilyResponseVo result = new PersonalUserFamilyResponseVo();
        result.setId(personalUserFamily.getId());
        result.setPatIdNo(personalUserFamily.getIdCardNo());
        result.setPatIdType(personalUserFamily.getIdCardType());
        result.setPatName(personalUserFamily.getUserName());
        result.setPatMobile(personalUserFamily.getMobile());
        result.setPatBirth(personalUserFamily.getBirth());
        result.setPatAddress(personalUserFamily.getAddress());
        result.setPatSex(personalUserFamily.getSex());
        result.setDataSource(personalUserFamily.getDataSource());
        result.setGuardIdCardNo(personalUserFamily.getGuardIdCardNo());
        result.setGuardIdCardType(personalUserFamily.getGuardIdCardType());
        result.setGuardName(personalUserFamily.getGuardName());
        result.setGuardMobile(personalUserFamily.getGuardMobile());
        result.setAppId(personalUserFamily.getAppId());
        result.setAppCode(personalUserFamily.getAppCode());
        result.setOpenId(personalUserFamily.getOpenId());
        result.setOwnership(personalUserFamily.getRelationType());
        result.setUserId(personalUserFamily.getUserId());
        result.setEnableFlag(personalUserFamily.getEnableFlag());
        result.setRealNameFlag(personalUserFamily.getRealNameFlag());
        result.setBindInsuranceCardFlag(personalUserFamily.getBindInsuranceCardFlag());
        result.setInsuranceLoginName(personalUserFamily.getInsuranceLoginName());
        result.setInsuranceLoginName(personalUserFamily.getInsuranceLoginName());
        result.setInsurancePassword(personalUserFamily.getInsurancePassword());

        return result;
    }

    /**
     * 删除就诊卡
     *
     * @param strData
     * @return
     */
    public ResponseObject deletePersonalCard(String strData) {
        ResponseObject responseObject = new ResponseObject();
        try {
            logger.info("删除就诊卡入参strData={}", strData);
            JSONObject jsonObject = JSONObject.parseObject(strData);
            String medicalCardId = jsonObject.getString("medical_card_id");
            if (StringUtils.isBlank(medicalCardId)) {
                responseObject.setResultCodeAndMessage("1001", "medical_card_id不能为空");
                return responseObject;
            }

            MedicalCard medicalCard = new MedicalCard();
            medicalCard.setId(medicalCardId);
            medicalCard.setEnableFlag(new Short("0"));
            medicalCardDao.update(medicalCard);
            responseObject.setResultCodeAndMessage("0", "移除就诊卡成功");
            logger.info("移除就诊卡成功");
        } catch (Exception e) {
            logger.error("移除就诊卡失败 errMsg ={}", e.getMessage());
            responseObject.setResultCodeAndMessage("-1", "移除就诊卡失败");
        }
        return responseObject;
    }

    /**
     * hopitalCode 不为空表示查询具体某家医院的卡，
     * hopitalCode 为空查询所有医院的卡
     * familyId 不为空查询具体某个就诊人的卡
     * familyId 为空查询该openid 下面所有就诊人的卡
     * 查询卡列表
     *
     * @param strData
     * @return
     */
    public ResponseObject listPersonalCard(String strData) {
        ResponseObject responseObject = new ResponseObject();
        logger.info("查询卡列表 strData={}", strData);
        try {
            StringBuilder sb = new StringBuilder();
            ListPersonalCardRequestVo requestVo = JsonUtils.parseObject(strData, ListPersonalCardRequestVo.class);
            if (StringUtils.isBlank(requestVo.getOpenId())) {
                responseObject.setResultCodeAndMessage("1001", "open_id不能为空");
                return responseObject;
            }
            long begin_1 = System.currentTimeMillis();
            PersonalUser personalUser = personalUserDao.selectPersonalUserByOpenId(requestVo.getOpenId());
            long end_1 = System.currentTimeMillis();
            sb.append("selectPersonalUserByOpenId:");
            sb.append(end_1 - begin_1);

            if (personalUser == null) {
                responseObject.setTime(sb.toString());
                logger.info("通过openId ={} 换取userId 失败", requestVo.getOpenId());
                responseObject.setResultCodeAndMessage("1001", "通过openId 换取userId 失败");
                return responseObject;
            }
            long begin_2 = System.currentTimeMillis();
            List<MedicalCard> medicalCardList = medicalCardDao.selectByUserId(requestVo.getHospitalCode(), personalUser.getId(), requestVo.getFamilyId());
            long end_2 = System.currentTimeMillis();
            sb.append(";selectByUserId:");
            sb.append(end_2 - begin_2);
            List<MedicalCardResponseVo> resultMedicalList = null;
            if (CollectionUtils.isNotEmpty(medicalCardList)) {
                resultMedicalList = new ArrayList<>();
                for (MedicalCard medicalCard : medicalCardList) {
                    resultMedicalList.add(buildMedicalCardResponseVo(medicalCard));
                }
            }
            responseObject.setResultCodeAndMessage("0", "成功");
            responseObject.setResultObject(resultMedicalList);
            logger.info("查询卡列表结果result ={}", new Object[]{JsonUtils.toJsonString(responseObject)});
        } catch (Exception e) {
            logger.error("查询卡列表异常errMsg={}", e.getMessage());
            responseObject.setResultCodeAndMessage("-1", "查询卡列表异常");
        }
        return responseObject;
    }

    private MedicalCardResponseVo buildMedicalCardResponseVo(MedicalCard medicalCard) {
        MedicalCardResponseVo result = new MedicalCardResponseVo();
        result.setId(medicalCard.getId());
        result.setPatIdNo(medicalCard.getIdCardNo());
        result.setPatIdType(medicalCard.getIdCardType());
        result.setPatCardNo(medicalCard.getMedicalCardNo());
        result.setPatCardType(medicalCard.getMedicalCardType());
        result.setPatName(medicalCard.getPatName());
        result.setPatMobile(medicalCard.getPatMobile());
        result.setPatBirth(medicalCard.getPatBirth());
        result.setHospitalCode(medicalCard.getOrgCode());
        result.setHospitalId(medicalCard.getOrgId());
        result.setHospitalName(medicalCard.getOrgName());
        result.setPatAddress(medicalCard.getPatAddress());
        result.setAdmissionNo(medicalCard.getAdmissionNo());
        result.setPatSex(medicalCard.getPatSex());
        result.setHisPatId(medicalCard.getHisPatId());
        result.setDataSource(medicalCard.getDataSource());
        result.setInsuranceCardNo(medicalCard.getInsuranceCardNo());
        result.setIsInsurance(medicalCard.getIsInsurance());
        result.setPatAge(medicalCard.getPatAge());
        result.setGuardIdCardNo(medicalCard.getGuardIdCardNo());
        result.setGuardIdCardType(medicalCard.getGuardIdCardType());
        result.setGuardName(medicalCard.getGuardName());
        result.setGuardMobile(medicalCard.getGuardMobile());
        result.setAppId(medicalCard.getAppId());
        result.setOpenId(medicalCard.getOpenId());
        result.setOwnership(medicalCard.getRelationType());
        result.setUserId(medicalCard.getUserId());
        result.setFamilyId(medicalCard.getFamilyId());
        result.setComputeNo(medicalCard.getComputeNo());
        return result;
    }

    private String checkRequestData(CreatePersonalCardRequestVo requestVo) {
        String errMsg = "";
        if (StringUtils.isEmpty(requestVo.getFamilyId())) {

            if (StringUtils.isBlank(requestVo.getPatName())) {
                errMsg = "患者姓名不能为空";
            }
            if (requestVo.getPlatformType() == null) {
                errMsg = "平台类型不能为空";
            }
        }
        return errMsg;
    }

    private String convertPatIdType(String patIdType) {
        if ("1".equals(patIdType)) {
            return "5";
        } else if ("2".equals(patIdType)) {
            return "13";
        } else if ("3".equals(patIdType)) {
            return "14";
        } else if ("4".equals(patIdType)) {
            return "15";
        } else if ("6".equals(patIdType)) {
            return "1";
        } else {
            return patIdType;
        }
    }

    /**
     * 绑卡
     *
     * @param strData
     * @return
     */
    @Transactional
    public ResponseObject createPersonalCard(String strData) throws CallException {
        ResponseObject responseObject = new ResponseObject();
        try {
            logger.info("绑卡入参strData={}", strData);
            CreatePersonalCardRequestVo requestVo = JsonUtils.parseObject(strData, CreatePersonalCardRequestVo.class);
            try {
                Validator.getInstance().validate(requestVo);
            } catch (ValidateException ex) {
                logger.info(" 数据校验失败 errMsg={}", ex.getMessage());
                logger.error("error", ex);
                responseObject.setResultCodeAndMessage("1001", "数据校验失败:" + ex.getMessage() + "！");
                return responseObject;
            }
            String errMsg = checkRequestData(requestVo);
            if (StringUtils.isNotEmpty(errMsg)) {
                responseObject.setResultCodeAndMessage("1001", errMsg);
                return responseObject;
            }
            StringBuilder sb = new StringBuilder();
            CreateCardVoResponse createCardVoResponse = null;
            PatientVoResponse queryHisPatientVoResponse = null;
            PersonalUserFamily personalUserFamily = null;
            try {
                //familyId 不为空说明就诊人已经存在过了不需要去添加就诊人了
                if (StringUtils.isNotEmpty(requestVo.getFamilyId())) {
                    sb.append("selectById:");
                    long begin_1 = System.currentTimeMillis();
                    personalUserFamily = personalUserFamilyDao.selectById(requestVo.getFamilyId());
                    long end_1 = System.currentTimeMillis();
                    sb.append("selectById:").append(end_1 - begin_1);
                    if (personalUserFamily == null) {
                        logger.info("传入的family_id ={}无法查询到对应的数据", requestVo.getFamilyId());
                        responseObject.setResultCodeAndMessage("1997", "传入的family_id无法查询到对应的数据");
                        responseObject.setTime(sb.toString());
                        return responseObject;
                    }
                    logger.info("通过family_id查询到的 personalUserFamily ={}", new Object[]{JsonUtils.toJsonString(personalUserFamily)});
                } else {
                    if (StringUtils.isNotEmpty(requestVo.getPatIdNo())) {
                        long begin_2 = System.currentTimeMillis();
                        List<PersonalUserFamily> dbPersonalUserFamilyList = personalUserFamilyDao.selectByIdNoAndUserId(requestVo.getPatIdNo(), requestVo.getUserId());
                        long end_2 = System.currentTimeMillis();
                        sb.append(";selectByIdNoAndUserId:").append(end_2 - begin_2);
                        logger.info("dbPersonalUserFamilyList ={}", new Object[]{JsonUtils.toJsonString(dbPersonalUserFamilyList)});
                        if (CollectionUtils.isNotEmpty(dbPersonalUserFamilyList)) {
                            personalUserFamily = dbPersonalUserFamilyList.get(0);
                        }
                        if (personalUserFamily == null) {
                            personalUserFamily = buildPersonalUserFamily(requestVo);
                            logger.info("当前添加就诊人 personalUserFamily ={}", new Object[]{JsonUtils.toJsonString(personalUserFamily)});
                            long begin_3 = System.currentTimeMillis();
                            personalUserFamilyDao.insert(personalUserFamily);
                            long end_3 = System.currentTimeMillis();
                            sb.append(";personalUserFamilyDao.insert:").append(end_3 - begin_3);
                        } else {
                            logger.info("通过身份证查询到的 personalUserFamily ={}", new Object[]{JsonUtils.toJsonString(personalUserFamily)});
                            personalUserFamily.setUpdateTime(DateUtils.dateToString(new Date()));
                            personalUserFamily.setUserName(requestVo.getPatName());
                            personalUserFamily.setMobile(requestVo.getPatMobile());
                            personalUserFamily.setBirth(requestVo.getPatBirth());
                            personalUserFamily.setOpenId(requestVo.getOpenId());
                            personalUserFamily.setRelationType(requestVo.getOwnership());
                            personalUserFamily.setEnableFlag(new Short("1"));
                            long begin_4 = System.currentTimeMillis();
                            personalUserFamilyDao.update(personalUserFamily);
                            long end_4 = System.currentTimeMillis();
                            sb.append(";personalUserFamilyDao.update:").append(end_4 - begin_4);
                        }
                    } else {
                        personalUserFamily = buildPersonalUserFamily(requestVo);
                        logger.info("当前当输入身份证为空时候都插入一条记录 personalUserFamily ={}", new Object[]{JsonUtils.toJsonString(personalUserFamily)});
                        long begin_5 = System.currentTimeMillis();
                        personalUserFamilyDao.insert(personalUserFamily);
                        long end_5 = System.currentTimeMillis();
                        sb.append(";personalUserFamilyDao.insert:").append(end_5 - begin_5);
                    }
                }
            } catch (CallException e) {
                logger.error("添加人或者更新就诊人信息时失败", e);
                logger.info("添加人或者更新就诊人信息时失败 errMsg ={}", e.getMessage());
                throw new CallException("1997", "添加人或者更新就诊人信息时失败");
            }
            /**
             规则校验疑问 比如 深三不需要校验身份证，这个时候入库的时候身份证没填，但是后面这个就诊人，
             又去北大建档，北大需要校验身份证不能为空。这个时候数据库中没有身份证。
             */


            MedicalCard medicalCard = null;
            if (requestVo.getBindCardType() == 1) {
                CreateCardVo createCardVo = null;
                ResCommon<CreateCardVoResponse> commonCreateCardVoResponse = null;
                try {
                    createCardVo = buildCreateCardVo(requestVo, personalUserFamily);
                    logger.info("患者首建档发给调度中心报文 createCardVo ={}", new Object[]{JsonUtils.toJsonString(createCardVo)});
                    long begin_6 = System.currentTimeMillis();
                    commonCreateCardVoResponse = HisifaceService.getHisifaceClient().createCard(createCardVo);
                    long end_6 = System.currentTimeMillis();
                    sb.append(";his createCard:").append(end_6 - begin_6);
                    logger.info("患者首建档出参报文 commonCreateCardVoResponse ={}", new Object[]{JsonUtils.toJsonString(commonCreateCardVoResponse)});
                    if (!"0".equals(commonCreateCardVoResponse.getResultCode())) {
                        throw new CallException("1001", HIS_CREATE_CARD_ERROR);
                    }
                    createCardVoResponse = commonCreateCardVoResponse.getResult();
                    medicalCard = buildMedicalCard(requestVo, personalUserFamily);
                    medicalCard.setBindWay(new Short(requestVo.getBindCardType().toString()));
                    medicalCard.setOpenId(requestVo.getOpenId());
                    medicalCard.setBindSourceAppCode(requestVo.getAppCode());
                    medicalCard.setMedicalCardNo(createCardVoResponse.getPatCardNo());
                    medicalCard.setMedicalCardType(new Short(createCardVoResponse.getPatCardType()));
                    medicalCard.setHisPatId(createCardVoResponse.getPatId());
                    medicalCard.setIsInsurance(requestVo.getIsInsurance());
                    medicalCard.setComputeNo(requestVo.getComputeNo());


                } catch (CallException e) {
                    logger.error("请求his首建档异常 errMsg={}", e);
                    throw new CallException("1001", HIS_CREATE_CARD_ERROR);
                }
            } else {
                PatientVo patientVo = null;
                ResCommon<PatientVoResponse> queryHisCardVoResponse = null;
                try {
                    patientVo = buildPatientVo(requestVo, personalUserFamily);

                    logger.info("患者信息查询发给调度中心报文 patientVo ={}", new Object[]{JsonUtils.toJsonString(patientVo)});
                    long begin_7 = System.currentTimeMillis();
                    queryHisCardVoResponse = HisifaceService.getHisifaceClient().getPatient(patientVo);
                    long end_7 = System.currentTimeMillis();
                    sb.append(";his getPatient:").append(end_7 - begin_7);
                    logger.info("患者信息查询出参报文 queryHisCardVoResponse ={}", new Object[]{JsonUtils.toJsonString(queryHisCardVoResponse)});
                    if (!"0".equals(queryHisCardVoResponse.getResultCode())) {
                        if (queryHisCardVoResponse.getResultMessage() != null && org.apache.commons.lang.StringUtils.isNotBlank(queryHisCardVoResponse.getResultMessage())) {
                            throw new CallException("1001", queryHisCardVoResponse.getResultMessage());
                        } else {
                            throw new CallException("1001", HIS_NO_PATIENT);
                        }
                    }
                    queryHisPatientVoResponse = queryHisCardVoResponse.getResult();
                    //状态码为0 也有可能患者信息为空的情况
                    if (queryHisPatientVoResponse == null) {
                        logger.info("查询his患者信息不存在");
                        throw new CallException("1001", HIS_NO_PATIENT);
                    }
                    long begin_8 = System.currentTimeMillis();
                    String ruleString = checkVaildRule(requestVo.getHospitalCode(), personalUserFamily, queryHisPatientVoResponse);
                    long end_8 = System.currentTimeMillis();
                    sb.append(";规则校验:").append(end_8 - begin_8);
                    if (StringUtils.isNotEmpty(ruleString)) {
                        throw new CallException("1001", ruleString);
                    }

                    medicalCard = buildMedicalCard(requestVo, personalUserFamily);
                    medicalCard.setBindWay(new Short(requestVo.getBindCardType().toString()));
                    medicalCard.setOpenId(requestVo.getOpenId());
                    medicalCard.setBindSourceAppCode(requestVo.getAppCode());
                    medicalCard.setPatBirth(queryHisPatientVoResponse.getPatBirth());
                    medicalCard.setPatMobile(queryHisPatientVoResponse.getPatMobile());
                    medicalCard.setPatName(queryHisPatientVoResponse.getPatName());
                    medicalCard.setMedicalCardNo(queryHisPatientVoResponse.getPatCardNo());
                    medicalCard.setMedicalCardType(new Short(queryHisPatientVoResponse.getPatCardType()));
                    medicalCard.setHisPatId(queryHisPatientVoResponse.getPatId());

                    medicalCard.setComputeNo(requestVo.getComputeNo());
                    medicalCard.setIsInsurance(requestVo.getIsInsurance());

                } catch (CallException e) {
                    logger.error("查询his异常 errMsg={}", e.getMessage());
                    throw new CallException("1997", e.getMessage());
                }
            }

            try {
                MedicalCard queryMedicalCard = new MedicalCard();
                queryMedicalCard.setOrgCode(requestVo.getHospitalCode());
                queryMedicalCard.setMedicalCardNo(medicalCard.getMedicalCardNo());
                queryMedicalCard.setUserId(requestVo.getUserId());
                queryMedicalCard.setEnableFlag(new Short("1"));
                long begin_9 = System.currentTimeMillis();
                List<MedicalCard> hasExistMedicalCard = medicalCardDao.select(queryMedicalCard);
                long end_9 = System.currentTimeMillis();
                sb.append(";medicalCardDao.select:").append(end_9 - begin_9);
                if (CollectionUtils.isNotEmpty(hasExistMedicalCard)) {
                    logger.info("hasExistMedicalCard ={}", new Object[]{JsonUtils.toJsonString(hasExistMedicalCard)});
                    responseObject.setResultCodeAndMessageAndResult("0", "成功",buildMedicalCardResponseVo(hasExistMedicalCard.get(0)));
                    responseObject.setTime(sb.toString());
                    return responseObject;
                }
                long begin_10 = System.currentTimeMillis();
                MedicalCard dbMedicalCard = medicalCardDao.selectByCardNoAndUserIdAndFamilyId(requestVo.getHospitalCode(), medicalCard.getMedicalCardNo(), requestVo.getUserId(), personalUserFamily.getId());
                long end_10 = System.currentTimeMillis();
                sb.append(";selectByCardNoAndUserIdAndFamilyId:").append(end_10 - begin_10);
                if (dbMedicalCard != null) {
                    logger.info("该就诊卡已经存在 更新 dbMedicalCard ={}", new Object[]{JsonUtils.toJsonString(dbMedicalCard)});
                    dbMedicalCard.setPatName(medicalCard.getPatName());
                    dbMedicalCard.setPatMobile(medicalCard.getPatMobile());
                    dbMedicalCard.setEnableFlag(new Short("1"));
                    dbMedicalCard.setUpdateTime(DateUtils.dateToString(new Date()));
                    long begin_11 = System.currentTimeMillis();
                    medicalCardDao.update(dbMedicalCard);
                    responseObject.setResultCodeAndMessageAndResult("0", "绑卡成功",buildMedicalCardResponseVo(dbMedicalCard));
                    long end_11 = System.currentTimeMillis();
                    sb.append(";medicalCardDao.update:").append(end_11 - begin_11);
                } else {
                    long begin_12 = System.currentTimeMillis();
                    logger.info("当前入库的就诊卡为 medicalCard ={}", new Object[]{JsonUtils.toJsonString(medicalCard)});
                    medicalCardDao.insert(medicalCard);
                    responseObject.setResultCodeAndMessageAndResult("0", "绑卡成功",buildMedicalCardResponseVo(medicalCard));
                    long end_12 = System.currentTimeMillis();
                    sb.append("; medicalCardDao.insert:").append(end_12 - begin_12);
                }
                responseObject.setTime(sb.toString());

            } catch (CallException e) {
                logger.error("添加就诊卡出错", e);
                throw new CallException(e.getResultCode(), e.getMessage());
            }


        } catch (CallException e) {
            logger.error("绑卡系统异常 errMsg={}", e);

            logger.error("绑卡系统异常 errMsg={}", e.getMessage());
            throw new CallException("1997", e.getMessage());
        }
        logger.info("绑卡接口出参返回 response={}",new Object[]{JsonUtils.toJsonString(responseObject)});
        return responseObject;
    }


    private String checkVaildRule(String hospitalCode, PersonalUserFamily personalUserFamily, PatientVoResponse queryHisPatientVoResponse) {
        String errMsg = "";
        String rule = getRule(hospitalCode, "bindCard", "");
        logger.info("获取规则绑卡规则 rule ={}", rule);
        if (StringUtils.isNotEmpty(rule)) {

            String ruleValue[] = rule.split(";");
            for (int i = 0; i < ruleValue.length; i++) {
                if ("1".equals(ruleValue[i])) {

                    if (!StringUtils.isEquals(personalUserFamily.getUserName(), queryHisPatientVoResponse.getPatName())) {
                        logger.info("提示：填写的姓名(" + personalUserFamily.getUserName() + ")跟医院登记的姓名(" + queryHisPatientVoResponse.getPatName() + ")的不一致，请检查后重新填写");
                        errMsg = "提示：填写的姓名跟医院登记的姓名不一致，请检查后重新填写";
                        break;
                    }
                } else if ("2".equals(ruleValue[i])) {
                    if (StringUtils.isNotEmpty(queryHisPatientVoResponse.getPatIdNo()) && !StringUtils.isEquals(personalUserFamily.getIdCardNo(), queryHisPatientVoResponse.getPatIdNo())) {
                        logger.info("提示：填写的身份证(" + personalUserFamily.getIdCardNo() + ")跟医院登记的身份证(" + queryHisPatientVoResponse.getPatIdNo() + ")不一致，请检查后重新填写");
                        errMsg = "提示：填写的身份证跟医院登记的身份证不一致，请检查后重新填写";
                        break;
                    }
                } else if ("3".equals(ruleValue[i])) {
                    if (!StringUtils.isEquals(personalUserFamily.getMobile(), queryHisPatientVoResponse.getPatMobile())) {
                        logger.info("提示：填写的手机号(" + personalUserFamily.getMobile() + ")跟医院登记的手机号码(" + queryHisPatientVoResponse.getPatMobile() + ")不一致，请检查后重新填写");
                        errMsg = "提示：填写的手机号跟医院登记的手机号码不一致，请检查后重新填写";
                        break;
                    }
                }else if("6".equals(ruleValue[i])){
                    MedicalCard queryMedicalCard = new MedicalCard();
                    queryMedicalCard.setMedicalCardNo(queryHisPatientVoResponse.getPatCardNo());
                    queryMedicalCard.setOrgCode(hospitalCode);
                    queryMedicalCard.setEnableFlag(new Short("1"));
                    List<MedicalCard> medicalCardList = medicalCardDao.select(queryMedicalCard);
                    if (CollectionUtils.isNotEmpty(medicalCardList) && !StringUtils.isEquals(personalUserFamily.getId(),medicalCardList.get(0).getFamilyId())){
                        errMsg = "提示：该卡已经被其他人绑定,请检查";
                        break;
                    }
                }
            }

        }
        logger.info("获取规则绑卡规则 返回 errMsg ={}", errMsg);

        return errMsg;
    }


    private MedicalCard buildMedicalCard(CreatePersonalCardRequestVo requestVo, PersonalUserFamily personalUserFamily) {
        MedicalCard medicalCard = new MedicalCard();
        medicalCard.setId(PKGenerator.generateId());
        Org org = orgServiceImpl.getOrgByCode(requestVo.getHospitalCode());

        medicalCard.setOrgName(org.getOrgName());
        medicalCard.setOrgCode(requestVo.getHospitalCode());
        medicalCard.setBranchCode(requestVo.getBranchCode());
        medicalCard.setBranchId(requestVo.getBranchId());
        medicalCard.setBranchName(requestVo.getBranchName());
        medicalCard.setOrgId(org.getId());

        medicalCard.setPatId(personalUserFamily.getId());
        medicalCard.setPatName(personalUserFamily.getUserName());
        medicalCard.setIdCardNo(personalUserFamily.getIdCardNo());
        medicalCard.setIdCardType(personalUserFamily.getIdCardType());
        medicalCard.setPatMobile(personalUserFamily.getMobile());
        medicalCard.setPatBirth(personalUserFamily.getBirth());
        medicalCard.setPatSex(personalUserFamily.getSex());
        medicalCard.setPatAge(personalUserFamily.getAge());
//        medicalCard.setGuardId(personalUserFamily.getgu);
        medicalCard.setGuardIdCardNo(personalUserFamily.getGuardIdCardNo());
        medicalCard.setGuardIdCardType(personalUserFamily.getGuardIdCardType());
        medicalCard.setGuardName(personalUserFamily.getGuardName());
        medicalCard.setGuardAddress(personalUserFamily.getGuardAddress());
        medicalCard.setUserId(personalUserFamily.getUserId());
        medicalCard.setFamilyId(personalUserFamily.getId());
        medicalCard.setAppId(personalUserFamily.getAppId());
        medicalCard.setRelationType(personalUserFamily.getRelationType());

        medicalCard.setEnableFlag(new Short("1"));
        medicalCard.setBindSourceFlag(requestVo.getPlatformType());
        medicalCard.setCreatedTime(DateUtils.dateToString(new Date()));
        return medicalCard;
    }

    private PersonalUserFamily buildPersonalUserFamily(CreatePersonalCardRequestVo requestVo) {
        PersonalUserFamily personalUserFamily = new PersonalUserFamily();
        personalUserFamily.setId(PKGenerator.generateId());
        personalUserFamily.setCreatedTime(DateUtils.dateToString(new Date()));
        personalUserFamily.setUpdateTime(DateUtils.dateToString(new Date()));
        personalUserFamily.setEnableFlag(new Short("1"));
        personalUserFamily.setMobile(requestVo.getPatMobile());
        personalUserFamily.setIdCardNo(requestVo.getPatIdNo());
        personalUserFamily.setIdCardType(requestVo.getPatIdType());
        personalUserFamily.setOpenId(requestVo.getOpenId());
        personalUserFamily.setUserId(requestVo.getUserId());
        personalUserFamily.setAppId(requestVo.getAppId());
        personalUserFamily.setAppCode(requestVo.getAppCode());
        personalUserFamily.setBirth(requestVo.getPatBirth());
        personalUserFamily.setUserName(requestVo.getPatName());
        personalUserFamily.setUserType(requestVo.getPatType());
        personalUserFamily.setRelationType(requestVo.getOwnership());
        personalUserFamily.setAddress(requestVo.getPatAddress());
        personalUserFamily.setSex(requestVo.getPatSex());
        personalUserFamily.setAge(requestVo.getPatAge());
        personalUserFamily.setGuardMobile(requestVo.getGuardMobile());
        personalUserFamily.setGuardName(requestVo.getGuardName());
        personalUserFamily.setGuardIdCardType(requestVo.getGuardIdCardType());
        personalUserFamily.setGuardIdCardNo(requestVo.getGuardIdCardNo());
        personalUserFamily.setDataSourceFlag(requestVo.getPlatformType());
        personalUserFamily.setInsuranceLoginName(requestVo.getInsuranceLoginName());
        personalUserFamily.setInsurancePassword(requestVo.getInsurancePassword());
        return personalUserFamily;
    }


    private CreateCardVo buildCreateCardVo(CreatePersonalCardRequestVo requestVo, PersonalUserFamily personalUserFamily) {
        CreateCardVo createCardVo = new CreateCardVo();
        createCardVo.setHospitalCode(requestVo.getHospitalCode());
        createCardVo.setBranchCode(requestVo.getBranchCode());
        createCardVo.setPatIdNo(personalUserFamily.getIdCardNo());
        createCardVo.setPatIdType(personalUserFamily.getIdCardType() == null ? "" : personalUserFamily.getIdCardType().toString());
        createCardVo.setPatName(personalUserFamily.getUserName());
        createCardVo.setPatBirth(personalUserFamily.getBirth());
        createCardVo.setPatSex(personalUserFamily.getSex() == null ? "3" : personalUserFamily.getSex().toString());
        createCardVo.setPatMobile(personalUserFamily.getMobile());
        createCardVo.setPatType(personalUserFamily.getUserType().toString());
        createCardVo.setGuardIdNo(personalUserFamily.getGuardIdCardNo());
        createCardVo.setGuardIdType(personalUserFamily.getGuardIdCardType() == null ? "" : personalUserFamily.getGuardIdCardType().toString());
        createCardVo.setGuardName(personalUserFamily.getGuardName());
        createCardVo.setPatAddress(personalUserFamily.getAddress());

        Map<String, Object> extMap = new HashMap<String, Object>();
        extMap.put("is_insurance ",requestVo.getIsInsurance());
        extMap.put("compute_no",requestVo.getComputeNo());
        createCardVo.setExtendParams(JsonUtils.toJsonString(extMap));


        createCardVo.setGuardMobile(personalUserFamily.getGuardMobile());
        return createCardVo;
    }

    private PatientVo buildPatientVo(CreatePersonalCardRequestVo requestVo, PersonalUserFamily personalUserFamily) {
        PatientVo patientVo = new PatientVo();
        patientVo.setHospitalCode(requestVo.getHospitalCode());
        patientVo.setBranchCode(requestVo.getBranchCode());
        patientVo.setPatName(requestVo.getPatName());
        if (StringUtils.isNotEmpty(requestVo.getPatCardNo())) {
            patientVo.setPatCardType(convertPatIdType(requestVo.getPatCardType().toString()));
            patientVo.setPatCardNo(requestVo.getPatCardNo());
        } else {
            patientVo.setPatCardType(convertPatIdType(personalUserFamily.getIdCardType().toString()));
            patientVo.setPatCardNo(personalUserFamily.getIdCardNo());
        }
        Map<String, Object> extMap = new HashMap<String, Object>();
        extMap.put("pat_age", personalUserFamily.getAge());
        extMap.put("pat_birth", personalUserFamily.getBirth());
        extMap.put("pat_sex", personalUserFamily.getSex());
        extMap.put("pat_mobile", personalUserFamily.getMobile());
        extMap.put("pat_id_type", personalUserFamily.getIdCardType());
        extMap.put("pat_id_no", personalUserFamily.getIdCardNo());

        patientVo.setExtendParams(JsonUtils.toJsonString(extMap));

        return patientVo;
    }

    private PatientVo buildPatientVo(CreatePersonalCardRequestVo requestVo) {
        PatientVo patientVo = new PatientVo();
        patientVo.setHospitalCode(requestVo.getHospitalCode());
        patientVo.setBranchCode(requestVo.getBranchCode());
        patientVo.setPatName(requestVo.getPatName());
        if (StringUtils.isNotEmpty(requestVo.getPatCardNo())) {
            patientVo.setPatCardType(requestVo.getPatCardType().toString());
            patientVo.setPatCardNo(requestVo.getPatCardNo());
        } else {
            patientVo.setPatCardType(requestVo.getPatCardType().toString());
            patientVo.setPatCardNo(requestVo.getPatIdNo());
        }
        return patientVo;
    }

    private String checkRequestData(QueryPatientVo requestVo) {
        String errMsg = "";
        if (StringUtils.isEmpty(requestVo.getFamilyId())) {
            if (requestVo.getPatCardType() == null) {
                errMsg = "卡类型不能为空";
                return errMsg;
            }
            if (StringUtils.isBlank(requestVo.getPatCardNo())) {
                errMsg = "身份证或就诊卡不能为空";
                return errMsg;
            }
            if (requestVo.getPatCardType() == 5) {
                if (StringUtils.isBlank(requestVo.getPatName())) {
                    errMsg = "卡类型是身份证时,姓名不能为空";
                    return errMsg;
                }
                if (!IdCardUtils.validateCard(requestVo.getPatCardNo())) {
                    errMsg = "身份证格式错误";
                    return errMsg;
                }
            }
        }
        return errMsg;
    }

    private PatientVo buildPatientVo(QueryPatientVo requestVo) {
        PatientVo patientVo = new PatientVo();
        patientVo.setHospitalCode(requestVo.getHospitalCode());
        patientVo.setBranchCode(requestVo.getBranchCode());
        patientVo.setPatCardNo(requestVo.getPatCardNo());
        patientVo.setPatName(requestVo.getPatName());
        patientVo.setPatCardType(convertPatIdType(requestVo.getPatCardType().toString()));


        Map<String, Object> extMap = new HashMap<String, Object>();
        if (patientVo.getPatCardType().equals("5")) {
            try {
                extMap.put("pat_age", IdCardUtils.getAgeByIdCard(requestVo.getPatCardNo()));
                extMap.put("pat_birth", YYYYMMDD.format(YYYYMMDD8.parse(IdCardUtils.getBirthByIdCard(requestVo.getPatCardNo()))));
                extMap.put("pat_sex", IdCardUtils.getGenderByIdCard(requestVo.getPatCardNo()).equalsIgnoreCase("F") ? 2 : 1);
                extMap.put("pat_id_type", 1);
                extMap.put("pat_id_no", requestVo.getPatCardNo());
            } catch (Exception e) {
                logger.error("获取扩展参数出错", e);
            }

        }

        extMap.put("pat_mobile", requestVo.getPatMobile());
        patientVo.setExtendParams(JsonUtils.toJsonString(extMap));
        return patientVo;
    }

    private PatientVo buildPatientVo(QueryPatientVo requestVo, PersonalUserFamily personalUserFamily) {
        PatientVo patientVo = new PatientVo();
        patientVo.setHospitalCode(requestVo.getHospitalCode());
        patientVo.setBranchCode(requestVo.getBranchCode());
        patientVo.setPatName(personalUserFamily.getUserName());
        if (requestVo.getPatCardType() != null && StringUtils.isNotEmpty(requestVo.getPatCardNo())) {
            patientVo.setPatCardNo(requestVo.getPatCardNo());
            patientVo.setPatCardType(convertPatIdType(requestVo.getPatCardType().toString()));
        } else {
            patientVo.setPatCardNo(personalUserFamily.getIdCardNo());
            patientVo.setPatCardType(convertPatIdType(personalUserFamily.getIdCardType().toString()));
        }

        Map<String, Object> extMap = new HashMap<String, Object>();
        extMap.put("pat_age", personalUserFamily.getAge());
        extMap.put("pat_birth", personalUserFamily.getBirth());
        extMap.put("pat_sex", personalUserFamily.getSex());
        extMap.put("pat_mobile", personalUserFamily.getMobile());
        extMap.put("pat_id_type", personalUserFamily.getIdCardType());
        extMap.put("pat_id_no", personalUserFamily.getIdCardNo());

        patientVo.setExtendParams(JsonUtils.toJsonString(extMap));

        return patientVo;
    }

    /**
     * 查询患者信息
     *
     * @param strData
     * @return
     */
    public ResponseObject queryPersonalHisPatient(String strData) {
        logger.info("患者信息查询原始入参strData ={}", strData);
        ResponseObject response = new ResponseObject();

        try {
            QueryPatientVo requestVo = JsonUtils.parseObject(strData, QueryPatientVo.class);
            try {
                //信息校验
                String errMsg = checkRequestData(requestVo);
                if (StringUtils.isNotEmpty(errMsg)) {
                    response.setResultCodeAndMessage("1001", errMsg);
                    return response;
                }

            } catch (Exception e) {
                logger.error("信息校验系统异常", e);
                response.setResultCodeAndMessage("1998", "信息校验系统异常");
                return response;
            }
            StringBuilder sb = new StringBuilder();

            PatientVo patientVo = null;
            if (StringUtils.isNotEmpty(requestVo.getFamilyId())) {
                long begin_1 = System.currentTimeMillis();
                PersonalUserFamily personalUserFamily = personalUserFamilyDao.selectById(requestVo.getFamilyId());
                long end_1 = System.currentTimeMillis();
                sb.append("selectById:").append(end_1 - begin_1);
                if (personalUserFamily == null) {
                    response.setResultCodeAndMessage("1001", "患者信息查询通过family_id 查询不到对应就诊人");
                    response.setTime(sb.toString());
                    return response;
                }
                patientVo = buildPatientVo(requestVo, personalUserFamily);
            } else {
                patientVo = buildPatientVo(requestVo);
            }

            PatientVoResponse patientVoResponse = null;
            try {
                long begin_2 = System.currentTimeMillis();
                logger.info("患者信息查询请求调度中心入参 patientVo ={}", new Object[]{JsonUtils.toJsonString(patientVo)});
                ResCommon<PatientVoResponse> commonPatientVoResponse = HisifaceService.getHisifaceClient().getPatient(patientVo);
                long end_2 = System.currentTimeMillis();
                sb.append("查hisgetPatient:").append(end_2 - begin_2);
                logger.info("患者信息查询调度中心出参 commonPatientVoResponse ={}", new Object[]{JsonUtils.toJsonString(commonPatientVoResponse)});
                if (!"0".equals(commonPatientVoResponse.getResultCode())) {
                    response.setResultCodeAndMessage("1998", commonPatientVoResponse.getResultMessage());
                    response.setTime(sb.toString());
                    return response;
                }
                patientVoResponse = commonPatientVoResponse.getResult();
                if (patientVoResponse == null) {
                    response.setTime(sb.toString());
                    response.setResultCodeAndMessage("1001", "查询his 无数据返回");
                    return response;
                }
            } catch (Exception e) {
                response.setTime(sb.toString());
                logger.error("患者信息查询his异常", e);
                response.setResultCodeAndMessage("1998", "查询his系统异常");
                return response;
            }

            /**组装返回对象**/
            PatientResponseResult result = new PatientResponseResult();
            result.setPatIdNo(patientVoResponse.getPatIdNo());
            result.setPatIdType(patientVoResponse.getPatIdType());
            result.setPatType(patientVoResponse.getPatType());
            result.setHospitalCode(patientVoResponse.getHospitalCode());
            result.setBranchCode(patientVoResponse.getBranchCode());
            result.setPatMobile(patientVoResponse.getPatMobile());
            result.setPatName(patientVoResponse.getPatName());
            result.setPatCardNo(patientVoResponse.getPatCardNo());
            result.setPatSex(patientVoResponse.getPatSex());
            result.setPatBirth(patientVoResponse.getPatBirth());
            result.setPatAddress(patientVoResponse.getPatAddress());
            result.setHisPatId(patientVoResponse.getPatId());
            result.setAdmissionNo(patientVoResponse.getAdmissionNo());
            result.setExtendParams(patientVoResponse.getExtendParams());
            result.setGuardIdNo(patientVoResponse.getGuardIdNo());
            result.setGuardIdType(patientVoResponse.getGuardIdType());
            result.setGuardMobile(patientVoResponse.getGuardMobile());
            result.setGuardName(patientVoResponse.getGuardName());
            result.setPatCardType(patientVoResponse.getPatCardType());
            result.setIsInsurance(patientVoResponse.getIsInsurance()==null?null:Short.parseShort(patientVoResponse.getIsInsurance()));
            response.setResultCodeAndMessageAndResult("0", "成功", result);
            logger.info("患者信息查询返回出参 result ={}", new Object[]{JsonUtils.toJsonString(result)});
            response.setTime(sb.toString());
            return response;
        } catch (Exception e) {
            logger.error("患者信息查询系统异常", e);
            response.setResultCodeAndMessage("-1", "患者信息查询系统异常");
            return response;
        }
    }

    /**
     * 患者首建档
     *
     * @param strData
     * @return
     */

    public ResponseObject updatePersonalHisCard(String strData) {
        ResponseObject response = new ResponseObject();
        logger.info("患者首建档原始入参 strData", strData);
        CreatePatientVo requestVo = JsonUtils.parseObject(strData, CreatePatientVo.class);
        try {
            Validator.getInstance().validate(requestVo);
        } catch (ValidateException ex) {
            logger.info(" 数据校验失败 errMsg={}", ex.getMessage());
            logger.error("error", ex);
            response.setResultCodeAndMessage("1001", "数据校验失败:" + ex.getMessage() + "！");
            return response;
        }
        CreateCardVo createCardVo = new CreateCardVo();
        createCardVo.setHospitalCode(requestVo.getHospitalCode());
        createCardVo.setPatType(requestVo.getPatType() == null ? "1" : requestVo.getPatType().toString());
        createCardVo.setPatName(requestVo.getPatName());
        createCardVo.setPatSex(requestVo.getPatSex());
        createCardVo.setPatBirth(requestVo.getPatBirth());
        createCardVo.setPatAddress(requestVo.getPatAddress());
        createCardVo.setPatMobile(requestVo.getPatMobile());
        createCardVo.setPatIdType(requestVo.getPatIdType() == null ? "1" : requestVo.getPatIdType().toString());
        createCardVo.setPatIdNo(requestVo.getPatIdNo());
        createCardVo.setGuardIdType(requestVo.getGuardIdCardType() == null ? "1" : requestVo.getGuardIdCardType().toString());
        createCardVo.setGuardName(requestVo.getGuardName());
        createCardVo.setGuardIdNo(requestVo.getGuardIdCardNo());
        Map<String, Object> extMap = new HashMap<String, Object>();
        extMap.put("is_insurance ",requestVo.getIsInsurance());
        extMap.put("compute_no",requestVo.getComputeNo());
        createCardVo.setExtendParams(JsonUtils.toJsonString(extMap));


        CreateCardVoResponse createCardVoResponse = null;
        try {
            logger.info("患者首建档给调度中心入参 createCardVo ={}", new Object[]{JsonUtils.toJsonString(createCardVo)});
            ResCommon<CreateCardVoResponse> commonCreateCardVoResponse = HisifaceService.getHisifaceClient().createCard(createCardVo);
            logger.info("患者首建档调度中心出参报文 commonCreateCardVoResponse ={} ", new Object[]{JsonUtils.toJsonString(commonCreateCardVoResponse)});
            if (!"0".equals(commonCreateCardVoResponse.getResultCode())) {
                response.setResultCodeAndMessage("1997", "患者首建档his失败");
                return response;
            }
            createCardVoResponse = commonCreateCardVoResponse.getResult();
            if (createCardVoResponse == null) {
                response.setResultCodeAndMessage("1001", "查询his 无数据返回");
                return response;
            }
        } catch (Exception e) {
            logger.error("患者首建档his系统异常");
            response.setResultCodeAndMessage("1998", "患者首建档his系统异常");
            return response;
        }

        logger.info("patIdNo={},更新患者类型--医保类型或者自费类型",requestVo.getPatIdNo());
        MedicalCard medicalCard = new MedicalCard();
        medicalCard.setComputeNo(requestVo.getComputeNo());
        medicalCard.setIsInsurance(requestVo.getIsInsurance());
        medicalCard.setOrgCode(requestVo.getHospitalCode());
        medicalCard.setMedicalCardNo(createCardVoResponse.getPatCardNo());
        medicalCard.setMedicalCardType(new Short(createCardVoResponse.getPatCardType()));
        medicalCardDao.updateInsuranceType(medicalCard);

        Map<String, String> resultMap = new HashMap<String, String>();
        resultMap.put("pat_card_no", createCardVoResponse.getPatCardNo());
        resultMap.put("pat_card_type", createCardVoResponse.getPatCardType());
        resultMap.put("his_pat_id", createCardVoResponse.getPatId());
        response.setResultCodeAndMessageAndResult("0", "成功", JsonUtils.toJsonString(resultMap));
        logger.info("患者首建档返回报文 response ={}", new Object[]{JsonUtils.toJsonString(response)});
        return response;
    }


    public static String getRule(String hospitalCode, String attributeName, String defaultValue) {
        String value = null;
        Map<String, String> ruleMap = new HashMap<String, String>();
        ruleMap.put("attribute_name", attributeName);
        ruleMap.put("org_code", hospitalCode);
        logger.info("获取规则绑卡入参 ruleMap ={}", new Object[]{JSON.toJSONString(ruleMap)});
        Response ruleResp = BaseService.callHumpFromInternal("yyt.base.rule.select", JSON.toJSONString(ruleMap));
        logger.info("BindCard yyt.base.rule.select response=" + JsonUtils.toJsonString(ruleResp));
        if ("0".equals(ruleResp.getResultCode())) {
            Rule rule = JsonUtils.parseObject(ruleResp.getResult(), Rule.class);
            if (rule != null && attributeName.equals(rule.getAttributeName())) {
                value = rule.getAttributeProperties();
            }
        }

        if (org.apache.commons.lang.StringUtils.isBlank(value)) {
            value = defaultValue;
        }
        return value;
    }

    public Response updatePersonalAdmissionNo(String strData) {
        Response response = new Response();
        logger.info("更新住院号原始入参 strData={}", strData);
        try {
            UpdateAdmissionNo updateAdmissionNo = JsonUtils.parseObject(strData, UpdateAdmissionNo.class);
            MedicalCard medicalCard = new MedicalCard();
            medicalCard.setId(updateAdmissionNo.getMedicalCardId());
            medicalCard.setAdmissionNo(updateAdmissionNo.getAdmissionNo());
            medicalCardDao.update(medicalCard);
            logger.info("更新住院号成功");
            response.setResultCodeAndMessage("0", "更新住院号成功");
            return response;
        } catch (Exception e) {
            logger.error("更新住院号异常errMsg={}", e);
            response.setResultCodeAndMessage("1999", "更新住院号异常");
            return response;
        }
    }


    /**
     * 绑卡
     *
     * @param strData
     * @return
     */
    @Transactional
    public ResponseObject createPersonalTgdCard(String strData) throws CallException {
        ResponseObject responseObject = new ResponseObject();
        try {
            logger.info("推广端绑卡入参strData={}", strData);
            CreatePersonalCardRequestVo requestVo = JsonUtils.parseObject(strData, CreatePersonalCardRequestVo.class);
            try {
                Validator.getInstance().validate(requestVo);
            } catch (ValidateException ex) {
                logger.info(" 数据校验失败 errMsg={}", ex.getMessage());
                responseObject.setResultCodeAndMessage("1001", "数据校验失败:" + ex.getMessage() + "！");
                return responseObject;
            }

            StringBuilder sb = new StringBuilder();
            CreateCardVoResponse createCardVoResponse = null;
            PatientVoResponse queryHisPatientVoResponse = null;
            PersonalUserFamily personalUserFamily = null;
            PersonalUser pu = null;

            try {
                //创建推广端用户
                PersonalUser wheres = new PersonalUser();
                wheres.setLoginName(requestVo.getPatMobile());
//                wheres.setAppId(requestVo.getAppId());
                List<PersonalUser> personalUsers = personalUserDao.select(wheres);
                logger.info("推广端新增注册用户, 根据username查询PersonalUser结果为:" + JsonUtils.toJsonString(personalUsers));

                if (CollectionUtils.isEmpty(personalUsers)) {
                    logger.info("推广端新增注册用户, 不存在用户" + requestVo.getPatMobile() + "的数据");
                    pu = new PersonalUser();
                    pu.setId(IDUtils.getUUID32());
                    pu.setLoginName(requestVo.getPatMobile());
                    pu.setSalt("123456");
                    pu.setPassword(MD5Util.string2MD5("123456" + pu.getSalt()));
                    pu.setUserName(requestVo.getPatName());
                    pu.setNickName(requestVo.getPatName());
                    pu.setIdCardNo(requestVo.getPatIdNo());
                    pu.setIdCardType(requestVo.getPatIdType());
                    pu.setInviteCode(requestVo.getInviteCode());
                    pu.setBirth(requestVo.getPatBirth());
                    pu.setMobile(requestVo.getPatMobile());
                    pu.setOpenId(pu.getId());
                    /** 默认启用 是否启用 0-禁用 1-启用', */
                    pu.setEnableFlag(new Short("1"));
                    pu.setRegisterTime(DateUtils.dateToString(new Date()));
                    pu.setLastLoginTime(DateUtils.dateToString(new Date()));
                    personalUserDao.insert(pu);
                } else {
                    pu = personalUsers.get(0);
                }

            } catch (CallException e) {
                logger.error("创建推广端用户异常 errMsg={}", e);
                throw new CallException("1001", "创建推广端用户异常");
            }

            try {
                //给推广端进来的患者创建家人
                if (StringUtils.isNotEmpty(requestVo.getPatIdNo())) {
                    PersonalUserFamily queryPersonalUserFamily = new PersonalUserFamily();
                    queryPersonalUserFamily.setIdCardNo(requestVo.getPatIdNo());
                    queryPersonalUserFamily.setUserId(pu.getId());
                    List<PersonalUserFamily> dbPersonalUserFamilyList = personalUserFamilyDao.select(queryPersonalUserFamily);
                    logger.info("dbPersonalUserFamilyList ={}", new Object[]{JsonUtils.toJsonString(dbPersonalUserFamilyList)});
                    if (CollectionUtils.isNotEmpty(dbPersonalUserFamilyList)) {
                        personalUserFamily = dbPersonalUserFamilyList.get(0);
                        if (personalUserFamily.getEnableFlag() == 0) {
                            personalUserFamily.setEnableFlag(new Short("1"));
                            personalUserFamilyDao.update(personalUserFamily);
                        }
                    }
                }

                if (personalUserFamily ==null){
                    personalUserFamily = new PersonalUserFamily();
                    personalUserFamily.setId(PKGenerator.generateId());
                    personalUserFamily.setCreatedTime(DateUtils.dateToString(new Date()));
                    personalUserFamily.setUpdateTime(DateUtils.dateToString(new Date()));
                    personalUserFamily.setEnableFlag(new Short("1"));
                    personalUserFamily.setMobile(requestVo.getPatMobile());
                    personalUserFamily.setIdCardNo(requestVo.getPatIdNo());
                    personalUserFamily.setIdCardType(requestVo.getPatIdType());
                    personalUserFamily.setOpenId(pu.getOpenId());
                    personalUserFamily.setUserId(pu.getId());
                    personalUserFamily.setAppId(requestVo.getAppId());
                    personalUserFamily.setAppCode(requestVo.getAppCode());
                    personalUserFamily.setBirth(requestVo.getPatBirth());
                    personalUserFamily.setUserName(requestVo.getPatName());
                    personalUserFamily.setUserType(requestVo.getPatType());
                    personalUserFamily.setRelationType(requestVo.getOwnership());
                    personalUserFamily.setAddress(requestVo.getPatAddress());
                    personalUserFamily.setSex(requestVo.getPatSex());
                    personalUserFamily.setAge(requestVo.getPatAge());
                    personalUserFamily.setGuardMobile(requestVo.getGuardMobile());
                    personalUserFamily.setGuardName(requestVo.getGuardName());
                    personalUserFamily.setGuardIdCardType(requestVo.getGuardIdCardType());
                    personalUserFamily.setGuardIdCardNo(requestVo.getGuardIdCardNo());
                    personalUserFamily.setDataSourceFlag(requestVo.getPlatformType());
                    logger.info("当前当输入身份证为空时候都插入一条记录 personalUserFamily ={}", new Object[]{JsonUtils.toJsonString(personalUserFamily)});
                    personalUserFamilyDao.insert(personalUserFamily);
                }

            } catch (CallException e) {
                logger.error("创建推广端家人信息异常 errMsg={}", e);
                throw new CallException("1001", "创建推广端家人信息异常");
            }


            //给推广端用户绑卡
            MedicalCard medicalCard = null;
            if (requestVo.getBindCardType() == 1) {
                CreateCardVo createCardVo = null;
                ResCommon<CreateCardVoResponse> commonCreateCardVoResponse = null;
                try {
                    createCardVo = buildCreateCardVo(requestVo, personalUserFamily);
                    logger.info("患者首建档发给调度中心报文 createCardVo ={}", new Object[]{JsonUtils.toJsonString(createCardVo)});
                    long begin_6 = System.currentTimeMillis();
                    commonCreateCardVoResponse = HisifaceService.getHisifaceClient().createCard(createCardVo);
                    long end_6 = System.currentTimeMillis();
                    sb.append(";his createCard:").append(end_6 - begin_6);
                    logger.info("患者首建档出参报文 commonCreateCardVoResponse ={}", new Object[]{JsonUtils.toJsonString(commonCreateCardVoResponse)});
                    if (!"0".equals(commonCreateCardVoResponse.getResultCode())) {
                        throw new CallException("1001", HIS_CREATE_CARD_ERROR);
                    }
                    createCardVoResponse = commonCreateCardVoResponse.getResult();
                    medicalCard = buildMedicalCard(requestVo, personalUserFamily);
                    medicalCard.setBindWay(new Short(requestVo.getBindCardType().toString()));
                    medicalCard.setOpenId(personalUserFamily.getOpenId());
                    medicalCard.setBindSourceAppCode(requestVo.getAppCode());
                    medicalCard.setMedicalCardNo(createCardVoResponse.getPatCardNo());
                    medicalCard.setMedicalCardType(new Short(createCardVoResponse.getPatCardType()));
                    medicalCard.setHisPatId(createCardVoResponse.getPatId());
                } catch (CallException e) {
                    logger.error("请求his首建档异常 errMsg={}", e);
                    throw new CallException("1001", HIS_CREATE_CARD_ERROR);
                }
            } else {
                PatientVo patientVo = null;
                ResCommon<PatientVoResponse> queryHisCardVoResponse = null;
                try {
                    patientVo = buildPatientVo(requestVo, personalUserFamily);
                    logger.info("患者信息查询发给调度中心报文 patientVo ={}", new Object[]{JsonUtils.toJsonString(patientVo)});
                    long begin_7 = System.currentTimeMillis();
                    queryHisCardVoResponse = HisifaceService.getHisifaceClient().getPatient(patientVo);
                    long end_7 = System.currentTimeMillis();
                    sb.append(";his getPatient:").append(end_7 - begin_7);
                    logger.info("患者信息查询出参报文 queryHisCardVoResponse ={}", new Object[]{JsonUtils.toJsonString(queryHisCardVoResponse)});
                    if (!"0".equals(queryHisCardVoResponse.getResultCode())) {
                        if (queryHisCardVoResponse.getResultMessage() != null && org.apache.commons.lang.StringUtils.isNotBlank(queryHisCardVoResponse.getResultMessage())) {
                            throw new CallException("1001", queryHisCardVoResponse.getResultMessage());
                        } else {
                            throw new CallException("1001", HIS_NO_PATIENT);
                        }
                    }
                    queryHisPatientVoResponse = queryHisCardVoResponse.getResult();
                    //状态码为0 也有可能患者信息为空的情况
                    if (queryHisPatientVoResponse == null) {
                        logger.info("查询his患者信息不存在");
                        throw new CallException("1001", HIS_NO_PATIENT);
                    }
                    long begin_8 = System.currentTimeMillis();
                    String ruleString = checkVaildRule(requestVo.getHospitalCode(), personalUserFamily, queryHisPatientVoResponse);
                    long end_8 = System.currentTimeMillis();
                    sb.append(";规则校验:").append(end_8 - begin_8);
                    if (StringUtils.isNotEmpty(ruleString)) {
                        throw new CallException("1001", ruleString);
                    }

                    medicalCard = buildMedicalCard(requestVo, personalUserFamily);
                    medicalCard.setBindWay(new Short(requestVo.getBindCardType().toString()));
                    medicalCard.setOpenId(personalUserFamily.getOpenId());
                    medicalCard.setBindSourceAppCode(requestVo.getAppCode());
                    medicalCard.setPatBirth(queryHisPatientVoResponse.getPatBirth());
                    medicalCard.setPatMobile(queryHisPatientVoResponse.getPatMobile());
                    medicalCard.setPatName(queryHisPatientVoResponse.getPatName());
                    medicalCard.setMedicalCardNo(queryHisPatientVoResponse.getPatCardNo());
                    medicalCard.setMedicalCardType(new Short(queryHisPatientVoResponse.getPatCardType()));
                    medicalCard.setHisPatId(queryHisPatientVoResponse.getPatId());

                } catch (CallException e) {
                    logger.error("查询his异常 errMsg={}", e.getMessage());
                    throw new CallException("1997", e.getMessage());
                }
            }

            try {
                MedicalCard queryMedicalCard = new MedicalCard();
                queryMedicalCard.setOrgCode(medicalCard.getOrgCode());
                queryMedicalCard.setMedicalCardNo(medicalCard.getMedicalCardNo());
                queryMedicalCard.setUserId(medicalCard.getUserId());
                long begin_9 = System.currentTimeMillis();
                List<MedicalCard> hasExistMedicalCard = medicalCardDao.select(queryMedicalCard);
                long end_9 = System.currentTimeMillis();
                sb.append(";medicalCardDao.select:").append(end_9 - begin_9);
                if (CollectionUtils.isNotEmpty(hasExistMedicalCard)) {
                    MedicalCard existMedicalCard = hasExistMedicalCard.get(0);
                    if (existMedicalCard.getEnableFlag() == 0) {
                        existMedicalCard.setEnableFlag(new Short("1"));
                        medicalCardDao.update(existMedicalCard);
                    }
                    logger.info("hasExistMedicalCard ={}", new Object[]{JsonUtils.toJsonString(hasExistMedicalCard)});
                    responseObject.setResultCodeAndMessageAndResult("0", "成功", buildMedicalCardResponseVo(existMedicalCard));
                    responseObject.setTime(sb.toString());
                } else {
                    long begin_12 = System.currentTimeMillis();
                    logger.info("当前入库的就诊卡为 medicalCard ={}", new Object[]{JsonUtils.toJsonString(medicalCard)});
                    medicalCardDao.insert(medicalCard);
                    long end_12 = System.currentTimeMillis();
                    sb.append("; medicalCardDao.insert:").append(end_12 - begin_12);
                    responseObject.setTime(sb.toString());
                    responseObject.setResultCodeAndMessageAndResult("0", "成功", buildMedicalCardResponseVo(medicalCard));
                }

            } catch (CallException e) {
                logger.error("添加就诊卡出错", e);
                throw new CallException(e.getResultCode(), e.getMessage());
            }

        } catch (CallException e) {
            logger.error("绑卡系统异常 errMsg={}", e.getMessage());
            throw new CallException("1997", e.getMessage());
        }
        logger.info("推广端绑卡出参 responseObject={}",new Object[]{JsonUtils.toJsonString(responseObject)});
        return responseObject;
    }

    public ResponseObject registerPersonalTgdAccount(String strData){
        ResponseObject responseObject = new ResponseObject();
        logger.info("查询当天注册用户入参data={}", strData);
        RegisterPersonalTgdRequest request = JsonUtils.parseObject(strData,RegisterPersonalTgdRequest.class);
        Map<String,Object> queryRegisterAccountMap = new HashMap<String,Object>();
        queryRegisterAccountMap.put("inviteCode",request.getInviteCode());
        if (request.getRegisterDays() != null){
            String registerTime = DateUtils.getDayForDate(new Date(), request.getRegisterDays()) + " 00:00:00";
            queryRegisterAccountMap.put("registerTime", registerTime);
        }
        Long dataCount = personalUserDao.selectRegisterTgdAccountNum(queryRegisterAccountMap);

        Map<String ,Object> resultMap = new HashMap<String ,Object>();
        resultMap.put("dataCount",dataCount);
        responseObject.setResultCodeAndMessageAndResult("0","成功",resultMap);
        logger.info("查询当天注册用户出参responseObject={}",new Object[]{JsonUtils.toJsonString(responseObject)});
        return responseObject;
    }

    /**
     * 同步his数据
     * @param strData
     * @return
     */
    public ResponseObject syncPersonalHisMessage(String strData){
        ResponseObject responseObject = new ResponseObject();
        Log.i(LogScene.PERSONAL,"同步his数据原始入参strData={}",strData);
        try {
            QueryPatientVo requestVo = JsonUtils.parseObject(strData, QueryPatientVo.class);
            MedicalCard medicalCard = new MedicalCard();
            PatientVo patientVo = null;
            ResCommon<PatientVoResponse> queryHisCardVoResponse = null;
            patientVo = buildPatientVo(requestVo);
            Log.i(LogScene.PERSONAL,"患者信息查询发给调度中心报文 patientVo ={}", new Object[]{JsonUtils.toJsonString(patientVo)});
            queryHisCardVoResponse = HisifaceService.getHisifaceClient().getPatient(patientVo);
            Log.i(LogScene.PERSONAL,"患者信息查询出参报文 queryHisCardVoResponse ={}", new Object[]{JsonUtils.toJsonString(queryHisCardVoResponse)});
            if (!"0".equals(queryHisCardVoResponse.getResultCode())) {
               responseObject.setResultCodeAndMessage("1001",queryHisCardVoResponse.getResultMessage());
                return responseObject;
            }

            PatientVoResponse queryHisPatientVoResponse = queryHisCardVoResponse.getResult();
            medicalCard.setOrgCode(requestVo.getHospitalCode());
            medicalCard.setPatBirth(queryHisPatientVoResponse.getPatBirth());
            medicalCard.setPatMobile(queryHisPatientVoResponse.getPatMobile());
            medicalCard.setPatName(queryHisPatientVoResponse.getPatName());
            medicalCard.setMedicalCardNo(queryHisPatientVoResponse.getPatCardNo());
            medicalCard.setMedicalCardType(new Short(queryHisPatientVoResponse.getPatCardType()));
            medicalCard.setPatSex(Short.valueOf(queryHisPatientVoResponse.getPatSex()));
            medicalCard.setIdCardNo(queryHisPatientVoResponse.getPatIdNo());
            medicalCard.setHisPatId(queryHisPatientVoResponse.getPatId());
            medicalCardDao.updateByPatCardNo(medicalCard);
            responseObject.setResultCodeAndMessage("0","同步信息成功");
            Log.i(LogScene.PERSONAL,"同步信息成功patCardNo={}",queryHisPatientVoResponse.getPatCardNo());
        }catch (Exception e){
            Log.e(LogScene.PERSONAL,"同步his数据失败errMsg={}",e);
            responseObject.setResultCodeAndMessage("1997","同步his数据失败");
        }
        return responseObject;
    }


}
